package com.heart.house.api.utils;

import com.heart.house.api.exception.RestException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.reflect.FieldUtils;

import java.util.concurrent.Callable;

/**
 * 二次封装Rest
 *
 * @author Luo Zhen
 * @create 2019-11-06 9:55
 */
@Slf4j
public class Rests {

    private Rests() {
    }

    private static DefaultHanlder defaultHandler = new DefaultHanlder();

    /**
     * 执行服务调用，判断返回状态
     *
     * @param callable
     * @param <T>
     * @return
     */
    public static <T> T excute(Callable<T> callable) {
        return excute(callable, defaultHandler);
    }

    public static <T> T excute(Callable<T> callable, ResultHandler handler) {
        T result = sendReq(callable);
        return handler.handle(result);
    }

    public static String toUrl(String serviceName, String path) {
        return "http://" + serviceName + path;
    }

    public static class DefaultHanlder implements ResultHandler {

        @Override
        public <T> T handle(T result) {
            int code = 1;
            String msg = "";
            try {
                code = (Integer) FieldUtils.readDeclaredField(result, "code", true);
                msg = (String) FieldUtils.readDeclaredField(result, "msg", true);
            } catch (Exception e) {
                //todo
            }
            if (code != 0) {
                throw new RestException("Get erroNo" + code + "when execute rest call with errorMsg");
            }
            return result;
        }
    }

    public interface ResultHandler {
        <T> T handle(T result);
    }

    /**
     * 封装请求连接，超时，抛出指定异常
     *
     * @param callable
     * @param <T>
     * @return
     */
    public static <T> T sendReq(Callable<T> callable) {
        T result = null;
        try {
            result = callable.call();
        } catch (Exception e) {
            throw new RestException("sendReq error");
        } finally {
            log.info("result={}", result);
        }
        return result;
    }

}
